package com.coderush.admin.sys.service.impl;

import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.coderush.admin.core.common.MyBatisPlusPageUtils;
import com.coderush.admin.core.common.PageResult;
import com.coderush.admin.core.component.SnowflakeIdGenerator;
import com.coderush.admin.core.utils.BeanConvertUtil;
import com.coderush.admin.core.utils.UserContext;
import com.coderush.admin.core.utils.UserContextModel;
import com.coderush.admin.sys.dao.CompanyDao;
import com.coderush.admin.sys.dao.RoleDao;
import com.coderush.admin.sys.dao.RoleMenuDao;
import com.coderush.admin.sys.exception.RoleException;
import com.coderush.admin.sys.model.dto.RoleAddDto;
import com.coderush.admin.sys.model.dto.RoleUpdateDto;
import com.coderush.admin.sys.model.entity.Company;
import com.coderush.admin.sys.model.entity.Role;
import com.coderush.admin.sys.model.vo.CompanyPageVo;
import com.coderush.admin.sys.model.vo.RolePageVo;
import com.coderush.admin.sys.service.RoleService;
import com.coderush.admin.sys.mapper.RoleMapper;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
* @author Administrator
* @description 针对表【sys_role(角色)】的数据库操作Service实现
* @createDate 2025-08-27 22:20:16
*/
@Service
public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements RoleService{

    @Resource
    private RoleDao roleDao;

    @Resource
    private SnowflakeIdGenerator snowflakeIdGenerator;

    @Resource
    private CompanyDao companyDao;

    @Resource
    private RoleMenuDao roleMenuDao;

    /**
     * 分页查询角色列表
     *
     * @param pageNum
     * @param pageSize
     * @param roleName
     * @return
     */
    @Override
    public PageResult<RolePageVo> findRolePage(Integer pageNum, Integer pageSize, String roleName) {

        // 获取当前用户信息
        UserContextModel user = UserContext.getUser();

        // 构建分页对象
        Page<Role> page = new Page<>(pageNum, pageSize);

        // 执行分页查询（会自动分页）
        Page<Role> rolePage = roleDao.findRolePage(page, roleName);

        // 将 MyBatis-Plus 的 IPage 转换为统一的 PageResult
        PageResult<Role> result = MyBatisPlusPageUtils.toPageResult(rolePage);

        // 数据模型转换 将 entity 转为 vo
        PageResult<RolePageVo> pageResult = new PageResult<>();
        pageResult.setTotal(result.getTotal());
        pageResult.setPages(result.getPages());
        pageResult.setPageNum(result.getPageNum());
        pageResult.setPageSize(result.getPageSize());

        List<RolePageVo> voList = new ArrayList<>();
        if (result.getList() != null && result.getList().size() > 0) {
            for (Role role : result.getList()) {
                var rolePageVo = JSON.parseObject(JSON.toJSONString(role), RolePageVo.class);
                BeanConvertUtil.fieldConvert(role, rolePageVo);
                voList.add(rolePageVo);
            }
        }

        pageResult.setList(voList);

        return pageResult;
    }

    /**
     * 删除角色
     * @param id
     * @return
     */
    @Override
    public Boolean deleteById(Long id) throws Exception {

        Role roleDB = roleDao.getById(id);
        if (roleDB == null) {
            throw RoleException.roleNotExist();
        }

        // 正在启动的角色不能被删除
        if (roleDB.getRoleStatus() == 1) {
            throw RoleException.roleStartedNotAllowedDelete();
        }

        // 系统管理员不允许删除
        if ("admin".equals(roleDB.getRoleCode())) {
            throw RoleException.systemRoleNotAllowedDelete();
        }

        // 逻辑删除角色
        roleDB.setUpdateBy(UserContext.getUser().getUserId());
        roleDB.setUpdateTime(LocalDateTime.now());
        roleDao.deleteById(roleDB);

        // 物理删除角色ID对应的所有菜单
        roleMenuDao.deleteByRoleId(id);

        return true;
    }

    /**
     * 修改角色
     * @param updateDto 修改角色参数
     * @return
     */
    @Override
    public Boolean update(RoleUpdateDto updateDto) throws Exception {

        // 角色不存在
        Role roleDB = roleDao.getById(updateDto.getId());
        if (roleDB == null) {
            throw RoleException.roleNotExist();
        }
        // 角色名称不能重复，查询排除此角色的数据，是否含有相同名称的角色
        Role secondRole = roleDao.getByRoleName(updateDto.getRoleName());
        // 根据角色名称查询如果为空，则修改了角色名称，并且角色名称不重复的，这是允许的
        // 如果不为空，则含有相同的角色名称，并且角色ID不是当前角色ID，则不允许修改
        if (secondRole != null && !Objects.equals(secondRole.getId(), roleDB.getId())) {
            throw RoleException.repeatRoleName();
        }

        var role = JSON.parseObject(JSON.toJSONString(updateDto), Role.class);

        return roleDao.update(role);
    }

    /**
     * 添加角色
     * @param addDto
     * @return
     */
    @Override
    public Boolean add(RoleAddDto addDto) throws Exception {

        // 角色名称不能重复
        Role roleDB = roleDao.getByRoleName(addDto.getRoleName());
        if (roleDB != null) {
            throw RoleException.repeatRoleName();
        }
        // 角色编码不能重复
        roleDB = roleDao.getByRoleCode(addDto.getRoleCode());
        if (roleDB != null) {
            throw RoleException.repeatRoleCode();
        }

        var role = JSON.parseObject(JSON.toJSONString(addDto), Role.class);

        // 角色类型：1-系统内置，2-自定义角色
        role.setRoleType(2);
        role.setId(snowflakeIdGenerator.nextId());

        return roleDao.add(role);
    }
}




